package org.chen.hotel.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.chen.common.hotel.dto.HotelApiConfigDTO;
import org.chen.common.hotel.request.HotelSearchRequest;
import org.chen.common.hotel.ConvenientAttraction;
import org.chen.common.hotel.dto.CustomAttractionDTO;
import org.chen.common.result.ResultVO;
import org.chen.hotel.feign.SystemClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.*;

@Service
@Slf4j
public class HotelService {

    private final RestTemplate restTemplate = new RestTemplate();
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private DataService dataService;

    @Autowired
    private SystemClient systemClient;

    @Autowired
    private ConvenientAttractionService attractionService;

    public Object searchHotels(HotelSearchRequest request) {
        log.info("开始查询酒店，参数：{}", request);
        try {
            // 构建请求体
            Map<String, Object> requestBody = buildRequestBody(request);

            HttpHeaders headers = getHeaders();

            HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);
            
            // 调用携程API
            String url = "https://m.ctrip.com/restapi/soa2/31454/json/fetchHotelList";
            ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);

            String responseBody = response.getBody();

            // 解析返回结果
            JsonNode jsonNode = objectMapper.readTree(responseBody);

            dataService.saveHotelsToDatabase(jsonNode, request);

            JSONObject jsonResponse = JSON.parseObject(responseBody);
            assert jsonResponse != null;
            JSONObject data = jsonResponse.getJSONObject("data");

            Map<String, Object> stringObjectMap = new HashMap<>();

            stringObjectMap.put("hotelList", data.getJSONArray("hotelList"));

            log.info("酒店数量：{} 个", data.getJSONArray("hotelList").size());

            return stringObjectMap;

        } catch (Exception e) {
            log.error(e.getMessage());
            return createErrorResponse("查询失败");
        }
    }

    private HttpHeaders getHeaders() {
        ResultVO<HotelApiConfigDTO> dto = systemClient.getHotelApiConfig();
        HotelApiConfigDTO hotelApiConfig = dto.getData();

        // 设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("User-Agent", hotelApiConfig.getAgent());
        headers.set("cookie", hotelApiConfig.getCookie());
        headers.set("phantom-token", hotelApiConfig.getPhantomToken());
        headers.set("p", hotelApiConfig.getP());
        return headers;
    }

    private Map<String, Object> buildRequestBody(HotelSearchRequest request) {
        Map<String, Object> body = new HashMap<>();
        
        // hotelIdFilter
        Map<String, Object> hotelIdFilter = new HashMap<>();
        hotelIdFilter.put("hotelAldyShown", new ArrayList<>());
        body.put("hotelIdFilter", hotelIdFilter);

        Map<String, Object> destination = new HashMap<>();
        destination.put("type", 1);
        Map<String, Object> geo = new HashMap<>();
        geo.put("cityId", request.getCityId());
        geo.put("countryId", request.getCountryId());
        destination.put("geo", geo);
        Map<String, Object> keyword = new HashMap<>();
        keyword.put("word", request.getKeyword() != null ? request.getKeyword() : "");
        destination.put("keyword", keyword);
        body.put("destination", destination);
        
        // date
        Map<String, Object> date = new HashMap<>();
        date.put("dateType", 1);
        Map<String, Object> dateInfo = new HashMap<>();
        dateInfo.put("checkInDate", request.getCheckInDate());
        dateInfo.put("checkOutDate", request.getCheckOutDate());
        date.put("dateInfo", dateInfo);
        body.put("date", date);
        
        // filters - 根据房间数生成
        List<Map<String, Object>> filters = buildFilters(request);
        body.put("filters", filters);
        
        // extraFilter
        Map<String, Object> extraFilter = new HashMap<>();
        if (request.getChildAges() != null && !request.getChildAges().isEmpty()) {
            List<Map<String, Object>> childInfoItems = new ArrayList<>();
            for (Integer age : request.getChildAges()) {
                Map<String, Object> childInfo = new HashMap<>();
                childInfo.put("age", age);
                childInfoItems.add(childInfo);
            }
            extraFilter.put("childInfoItems", childInfoItems);
        }
        extraFilter.put("sessionId", "");
        body.put("extraFilter", extraFilter);
        
        // paging
        Map<String, Object> paging = new HashMap<>();
        paging.put("pageCode", "102102");
        paging.put("pageIndex", request.getPageIndex());
        paging.put("pageSize", request.getPageSize());
        body.put("paging", paging);
        
        // 其他固定参数
        body.put("roomQuantity", request.getRoomQuantity());
        
        Map<String, Object> recommend = new HashMap<>();
        recommend.put("nearbyHotHotel", new HashMap<>());
        body.put("recommend", recommend);
        
        body.put("genk", true);
        body.put("residenceCode", "CN");

        ResultVO<HotelApiConfigDTO> dto = systemClient.getHotelApiConfig();
        HotelApiConfigDTO hotelApiConfig = dto.getData();

        // head
        Map<String, Object> head = new HashMap<>();
        head.put("platform", "PC");
        head.put("cid", hotelApiConfig.getCid());
        head.put("cver", "hotels");
        head.put("bu", "HBU");
        head.put("group", "ctrip");
        head.put("aid", hotelApiConfig.getAid());
        head.put("sid", hotelApiConfig.getSid());
        head.put("ouid", "");
        head.put("locale", "zh-CN");
        head.put("timezone", "8");
        head.put("currency", "CNY");
        head.put("pageId", "102102");
        head.put("vid", hotelApiConfig.getVid());
        head.put("guid", hotelApiConfig.getGuid());
        head.put("isSSR", false);
        body.put("head", head);
        
        body.put("ServerData", "");
        
        return body;
    }

    private List<Map<String, Object>> buildFilters(HotelSearchRequest request) {
        List<Map<String, Object>> filters = new ArrayList<>();

        // 1. 添加成人信息 filter（必有）
        Map<String, Object> adultFilter = new HashMap<>();
        adultFilter.put("filterId", "29|1");
        adultFilter.put("type", "29");
        adultFilter.put("value", "1|" + request.getAdultCount());
        adultFilter.put("subType", "2");
        filters.add(adultFilter);

        // 2. 添加儿童信息 filters（如果有儿童）
        if (request.getChildAges() != null && !request.getChildAges().isEmpty()) {
            for (Integer childAge : request.getChildAges()) {
                Map<String, Object> childFilter = new HashMap<>();
                childFilter.put("filterId", "29|2|" + childAge);
                childFilter.put("type", "29");
                childFilter.put("value", "2|" + childAge);
                childFilter.put("subType", "2");
                filters.add(childFilter);
            }
        }

        // 3. 添加排序方式 filter
        String sortType = request.getSortType() != null ? request.getSortType() : "9"; // 默认智能排序
        Map<String, Object> sortFilter = new HashMap<>();
        sortFilter.put("filterId", "17|" + sortType);
        sortFilter.put("type", "17");
        sortFilter.put("subType", "2");
        sortFilter.put("value", sortType);

        // 添加对应的标题
        String sortTitle = getSortTitle(sortType);
        if (sortTitle != null) {
            sortFilter.put("title", sortTitle);
        }

        filters.add(sortFilter);

        // 4. 添加景点 filters
        addAttractionFilters(filters, request);

        return filters;
    }
    
    private Map<String, Object> createErrorResponse(String message) {
        Map<String, Object> errorResponse = new HashMap<>();
        errorResponse.put("error", true);
        errorResponse.put("message", message);
        return errorResponse;
    }

    /**
     * 根据排序类型获取标题
     */
    private String getSortTitle(String sortType) {
        return switch (sortType) {
            case "5" -> "距离";
            case "6" -> "好评优先";
            case "9" -> "智能排序";
            case "14" -> "高星优先";
            default -> null;
        };
    }

    /**
     * 添加景点相关的filters
     */
    private void addAttractionFilters(List<Map<String, Object>> filters, HotelSearchRequest request) {
        // 处理便捷景点（单选）
        if (request.getConvenientAttractionId() != null) {
            ConvenientAttraction attraction = attractionService.getAttractionById(request.getConvenientAttractionId());
            if (attraction != null) {
                Map<String, Object> attractionFilter = new HashMap<>();
                attractionFilter.put("filterId", "50|50");
                attractionFilter.put("type", "50");
                attractionFilter.put("value", buildAttractionFilterValue(
                        attraction.getLatitude().toString(),
                        attraction.getLongitude().toString(),
                        attraction.getName()
                ));
                attractionFilter.put("subType", "2");
                filters.add(attractionFilter);
            }
        }

        // 处理自定义景点（单个）
        if (request.getCustomAttraction() != null) {
            CustomAttractionDTO customAttraction = request.getCustomAttraction();
            Map<String, Object> attractionFilter = new HashMap<>();
            attractionFilter.put("filterId", "50|50");
            attractionFilter.put("type", "50");
            attractionFilter.put("value", buildAttractionFilterValue(
                    customAttraction.getLatitude().toString(),
                    customAttraction.getLongitude().toString(),
                    customAttraction.getName()
            ));
            attractionFilter.put("subType", "2");
            filters.add(attractionFilter);
        }
    }

    /**
     * 构建景点filter的value值
     */
    private String buildAttractionFilterValue(String latitude, String longitude, String name) {
        return String.format("%s|%s|%s|2", latitude, longitude, name);
    }
}